home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / pas / swag / memory.swg / 0057_Lim EMS Library.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-24  |  9KB  |  296 lines

  1. {This unit is a kit to EMS functions.}
  2.  
  3. Unit EMSLib;
  4. { Copyright (c) 1994 by Andrew Eigus            FidoNet: 2:5100/33 }
  5. { LIM EMS Interface V1.01 for Turbo Pascal version 7.0 }
  6.  
  7. (*
  8.   Material used:
  9.     Interrupt List V1.02 (WindowBook) (c) 1984-90 Box Company, Inc.
  10.     Tech Help V4.50
  11. *)
  12.  
  13. {$X+} { Enable extended syntax }
  14. {$G+} { Enable 286 instructions }
  15.  
  16. interface
  17.  
  18. const
  19.  
  20.   PageSize = 16384;  { EMS Page size: 16384 bytes }
  21.  
  22.   { LIM EMS 3+ function numbers }
  23.  
  24.   EGetPageFrame  = $41;
  25.   EGetPageCount  = $42;
  26.   EAllocPages    = $43;
  27.   EMapPages      = $44;
  28.   EReleasePages  = $45;
  29.   EGetVersion    = $46;
  30.  
  31.   { LIM EMS functions result codes }
  32.  
  33.   emsrOk            = $00; { Function successful }
  34.   emsrNotInitd      = $01; { EMS not installed }
  35.   emsrIntrnlError   = $80; { Internal error }
  36.   emsrHardwareMalf  = $81; { Hardware malfunction }
  37.   emsrBadHandle     = $83; { Invalid handle }
  38.   emsrBadFunction   = $84; { Undefined function requested }
  39.   emsrNoMoreHandles = $85; { No more handles available }
  40.   emsrMapContError  = $86; { Error in save or restore of mapping context }
  41.   emsrMorePagesPhys = $87; { More pages requested than physically exist }
  42.   emsrMorePagesCurr = $88; { More pages requested than currently available }
  43.   emsrZeroPages     = $89; { Zero pages requested }
  44.   emsrBadPageLogNum = $8A; { Invalid page logical number }
  45.   emsrBadPagePhyNum = $8B; { Invalid page physical number }
  46.  
  47. function EMS_Setup : boolean;
  48. function EMS_GetVersion(var Version : byte) : byte;
  49. function EMS_GetMemAvail(var FreeMem : word) : byte;
  50. function EMS_AllocEMB(var Handle, PageSeg : word; Pages : word) : byte;
  51. function EMS_FreeEMB(Handle : word) : byte;
  52. function EMS_MapPages(Handle, LogicalPage : word; PhysicalPage : byte) : byte;
  53.  
  54. function EMS_GetErrorMsg(ErrorCode : byte) : string;
  55.  
  56. implementation
  57.  
  58. const
  59.   DOS = $21; { DOS interrupt number }
  60.   EMS = $67; { EMS interrupt number }
  61.  
  62. var
  63.   EMSInitd : boolean;
  64.  
  65. Function EMS_Setup; assembler;
  66. { EMM Installation check }
  67. const DeviceDriver : PChar = 'EMMXXXX0';
  68. Asm
  69.   MOV EMSInitd,False
  70.   PUSH DS
  71.   MOV AX,3D02h        { DOS function to open the device as file }
  72.   LDS DX,DeviceDriver
  73.   INT DOS
  74.   POP DS
  75.   JC  @@1
  76.   PUSH AX             { store device handle to close the file afterwards }
  77.   MOV AX,4407h        { DOS function to test device status }
  78.   INT DOS
  79.   MOV EMSInitd,AL
  80.   POP BX
  81.   MOV AH,3Eh          { close the file using it's handle in BX }
  82.   INT DOS
  83. @@1:
  84.   MOV AL,EMSInitd
  85. End; { EMS_Setup }
  86.  
  87. Function EMS_GetVersion; assembler;
  88. { Get Expanded Memory Manager version number }
  89. Asm
  90.   MOV AL,emsrNotInitd
  91.   CMP EMSInitd,False  { If library not initialized by EMS_Setup }
  92.   JE  @@1             { then exit }
  93.   MOV AH,EGetVersion  { Get EMS version }
  94.   INT EMS
  95.   LES DI,Version
  96.   MOV [ES:DI],AL      { Store version number }
  97.   MOV AL,AH           { Store result byte }
  98. @@1:
  99. End; { EMS_GetVersion }
  100.  
  101. Function EMS_GetMemAvail; assembler;
  102. { Returns free memory in FreeMem parameter }
  103. Asm
  104.   MOV AL,emsrNotInitd
  105.   CMP EMSInitd,False
  106.   JE  @@1
  107.   MOV AH,EGetPageCount
  108.   INT EMS
  109.   SHL BX,4            { Got in pages, convert to K-bytes }
  110.   LES DI,FreeMem
  111.   MOV [ES:DI],BX      { Store memory available in K-Bytes }
  112.   MOV AL,AH           { Store result byte }
  113. @@1:
  114. End; { EMS_GetMemAvail }
  115.  
  116. Function EMS_AllocEMB; assembler;
  117. { Allocates specified number of 16 K-byte pages and returns handle number in
  118.   Handle parameter. Page frame segment address stored in PageSeg. To access
  119.   data, use the following function:
  120.      DataPtr := Ptr(PageSeg, PhysicalPageNumber * PageSize) }
  121. Asm
  122.   MOV AL,emsrNotInitd
  123.   CMP EMSInitd,False
  124.   JE  @@2
  125.   MOV AH,EGetPageFrame
  126.   INT EMS
  127.   CMP AH,0
  128.   JNE @@1
  129.   LES DI,PageSeg      { Store page frame segment }
  130.   MOV [ES:DI],BX
  131.   MOV BX,Pages
  132.   MOV AH,EAllocPages
  133.   INT EMS
  134.   LES DI,Handle
  135.   MOV [ES:DI],DX      { Store handle number }
  136. @@1:
  137.   MOV AL,AH           { Return result code }
  138. @@2:
  139. End; { EMS_AllocEMB }
  140.  
  141. Function EMS_FreeEMB; assembler;
  142. { Deallocates (releases) allocated expanded memory }
  143. Asm
  144.   MOV AL,emsrNotInitd
  145.   CMP EMSInitd,False
  146.   JE  @@1
  147.   MOV AH,EReleasePages
  148.   MOV DX,Handle
  149.   INT EMS
  150.   MOV AL,AH           { Return result code }
  151. @@1:
  152. End; { EMS_FreeEMB }
  153.  
  154. Function EMS_MapPages; assembler;
  155. { Maps a logical page number at physical page number }
  156. Asm
  157.   MOV AL,emsrNotInitd
  158.   CMP EMSInitd,False
  159.   JE  @@1
  160.   MOV AH,EMapPages
  161.   MOV DX,Handle
  162.   MOV BX,LogicalPage
  163.   MOV AL,PhysicalPage
  164.   INT EMS
  165.   MOV AL,AH
  166. @@1:
  167. End; { EMS_MapPages }
  168.  
  169. Function EMS_GetErrorMsg;
  170. { Get an error message according to ErrorCode }
  171. Begin
  172.   case ErrorCode of
  173.     emsrNotInitd:      EMS_GetErrorMsg := 'EMM not initialized';
  174.     emsrIntrnlError:   EMS_GetErrorMsg := 'Internal error';
  175.     emsrHardwareMalf:  EMS_GetErrorMsg := 'Hardware malfunction';
  176.     emsrBadHandle:     EMS_GetErrorMsg := 'Invalid block handle';
  177.     emsrBadFunction:   EMS_GetErrorMsg := 'Function not implemented';
  178.     emsrNoMoreHandles: EMS_GetErrorMsg := 'No more handles available';
  179.     emsrMapContError:  EMS_GetErrorMsg := 'Error in save or restore of ' +
  180. 'mapping context';
  181.     emsrMorePagesPhys: EMS_GetErrorMsg := 'More pages requested than ' +
  182. 'physically exist';
  183.     emsrMorePagesCurr: EMS_GetErrorMsg := 'More pages requested than ' +
  184. 'currently available';
  185.     emsrZeroPages:     EMS_GetErrorMsg := 'Zero pages requested';
  186.     emsrBadPageLogNum: EMS_GetErrorMsg := 'Invalid page logical number';
  187.     emsrBadPagePhyNum: EMS_GetErrorMsg := 'Invalid page physical number';
  188.     else EMS_GetErrorMsg := 'Unknown error'
  189.   end
  190. End; { EMS_GetErrorMsg }
  191.  
  192. Begin
  193.   EMSInitd := False
  194. End. { EMSLib }
  195.  
  196. { --------------------------   DEMO --------------------------------- }
  197.  
  198. Program EMSLibDemo;
  199. { Copyright (c) 1994 by Andrew Eigus                  FidoNet: 2:5100/33 }
  200. { LIM EMS Interface V1.01 for Turbo Pascal version 7.0 demonstration program }
  201.  
  202. (*
  203.   Tested on IBM 486 SX 33Mhz with 4MB RAM with the following configuration:
  204.         HIMEM.SYS  (MS-DOS 6.2 XMS memory manager)
  205.         EMM386.EXE (MS-DOS 6.2 EMS memory manager)
  206.  
  207.   If any bugs occur in your system while running this demo,
  208.   please inform me:
  209.  
  210.  AndRew's BBS Phone: 003-712-559777 (Riga, Latvia) 24h 2400bps
  211.  Voice Phone:     003-712-553218
  212.  FidoNet:     2:5100/33
  213.  E-Mail:      aeigus@fgate.castle.riga.lv
  214. *)
  215.  
  216. {$X+}{$R-} { Enable extended syntax }
  217.  
  218. uses EMSLib;
  219.  
  220. type TMsg = array[1..13] of Char;
  221.  
  222. const
  223.   Message1 : TMsg = 'First string ';
  224.   Message2 : TMsg = 'Second string';
  225.  
  226. var
  227.   Version : byte;
  228.   FreeMemory, Handle, SegAddr, I : word;
  229.   P : pointer;
  230.  
  231. Function Hex(Num : longint; Places : byte) : string;
  232. const HexTab : array[0..15] of Char = '0123456789ABCDEF';
  233. var
  234.   HS : string[8];
  235.   Digit : byte;
  236. Begin
  237.   HS[0] := Chr(Places);
  238.   for Digit := Places downto 1 do
  239.   begin
  240.     HS[Digit] := HexTab[Num and $0000000F];
  241.     Num := Num shr 4
  242.   end;
  243.   Hex := HS
  244. End; { Hex }
  245.  
  246. Function Check(Result : byte; Func : string) : byte;
  247. Begin
  248.   if Result <> emsrOk then
  249.     WriteLn(Func, ' returned ',
  250.       Hex(Result, 2), 'h (', Result, '): ', EMS_GetErrorMsg(Result));
  251.   Check := Result
  252. End; { Check }
  253.  
  254. Procedure PrintFreeMemory;
  255. Begin
  256.   WriteLn;
  257.   if Check(EMS_GetMemAvail(FreeMemory), 'EMS_GetMemAvail') = emsrOk then
  258.     WriteLn('EMS memory available: ', FreeMemory, ' KB');
  259.   WriteLn
  260. End; { PrintFreeMemory }
  261.  
  262. Begin
  263.   WriteLn('LIM EMS Library V1.01 Demonstration program by Andrew Eigus'#10);
  264.   if EMS_Setup then
  265.   begin
  266.     if Check(EMS_GetVersion(Version), 'EMS_GetVersion') = emsrOk then
  267.       WriteLn('EMS driver version ',
  268.         Version shr 4, '.', Version shr 8, ' detected');
  269.     PrintFreeMemory;
  270.     if FreeMemory = 0 then Halt(8);
  271.     if Check(EMS_AllocEMB(Handle, SegAddr, 1), 'EMS_AllocEMB') = emsrOk then
  272.     begin
  273.       WriteLn('Message1: ', Message1);
  274.       WriteLn('Message2: ', Message2);
  275.       WriteLn('16 KB (one page) of EMS allocated. Linear address: ',
  276.         Hex(SegAddr, 8), 'h');
  277.       PrintFreeMemory;
  278.       WriteLn('Transferring Message1 to EMS...');
  279.       for I := 0 to SizeOf(TMsg) - 1 do
  280.         EMS_MapPages(Handle, I, 0);
  281.       P := Ptr(SegAddr, 0);
  282.       Move(Message1, P^, SizeOf(TMsg));
  283.       WriteLn('Transferring Message1 from EMS to Message2...');
  284.       Move(P^, Message2, SizeOf(TMsg));
  285.       WriteLn('Message1: ', Message1);
  286.       WriteLn('Message2: ', Message2);
  287.       if Check(EMS_FreeEMB(Handle), 'EMS_FreeEMB') = emsrOk then
  288.       begin
  289.         WriteLn('Memory deallocated (released). ');
  290.         PrintFreeMemory
  291.       end
  292.     end
  293.   end else
  294.     WriteLn('EMM386 manager not installed.');
  295. End.
  296.